package vn.edu.hcmut.cse.ai.search.problems.waterjug;

import vn.edu.hcmut.cse.ai.infrastructure.Action;
import vn.edu.hcmut.cse.ai.infrastructure.ActionCost;
import vn.edu.hcmut.cse.ai.infrastructure.Node;
import vn.edu.hcmut.cse.ai.infrastructure.Problem;

public class WaterProblem extends Problem {

    public WaterProblem(WaterState initState, WaterActions actions, WaterGoalTest goalTest, ActionCost actionCost) {
        super(initState, actions, goalTest, actionCost);
    }

    @Override
    public Node getChildNode(Node node, Action action) {
        WaterAction waterAction = (WaterAction) action;
        WaterState waterState = new WaterState((WaterState) node.getState());
        switch (waterAction.getActionType()) {
            case EMPTY1:
                waterState.empty1();
                waterState.clearUndo();
                break;
            case EMPTY2:
                waterState.empty2();
                waterState.clearUndo();
                break;
            case FILL1:
                waterState.fill1();
                waterState.clearUndo();
                break;
            case FILL2:
                waterState.fill2();
                waterState.clearUndo();
                break;
            case FILL1FROM2:
                waterState.fill1from2();
                waterState.clearUndo();
                break;
            case FILL2FROM1:
                waterState.fill2from1();
                waterState.clearUndo();
                break;
            case POURALL1TO2:
                waterState.pourAll1to2();
                waterState.clearUndo();
                break;
            case POURALL2TO1:
                waterState.pourAll2to1();
                waterState.clearUndo();
                break;
            default:
                return null;
        }
        double stepCost = this.actionCost.actionCost(node.getState(), waterState, action);
        Node returnNode = new Node(waterState, node, waterAction, stepCost);
        return returnNode;
    }
}
